const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
const multer = require('multer');
const bodyParser = require('body-parser');
const path = require('path');
const fs = require('fs');
const app = express();
const PORT = 5000;
const bcrypt = require('bcrypt'); // 用于密码加密
const jwt = require('jsonwebtoken'); // 用于生成令牌
const { GridFSBucket, ObjectId } = require('mongodb'); // 用于GridFS存储
const crypto = require('crypto'); // 用于生成随机文件名

app.use(cors({
    origin: 'http://localhost:5173',
    methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许的请求方法
    allowedHeaders: ['Content-Type', 'Authorization'], // 允许的请求头
    credentials: true,// 允许跨域携带凭证
}));
app.use(express.json());//解析json
app.use(bodyParser.json()); //解析json

// 创建上传目录 (仍然保留用于临时文件)
const uploadDir = path.join(__dirname, 'uploads');
if (!fs.existsSync(uploadDir)) {
    fs.mkdirSync(uploadDir, { recursive: true });
}

// const mongoURI = 'mongodb://localhost:27017/mydb';
const mongoURI = 'mongodb+srv://1297416402:wlrm9akd10boc4cM@cluster0.wggq5m9.mongodb.net/mydb';

mongoose.connect(mongoURI, { useNewUrlParser: true, useUnifiedTopology: true, serverSelectionTimeoutMS: 20000 })
    .then(() => {
        console.log('MongoDB 连接成功');

        // 初始化GridFS
        const db = mongoose.connection.db;
        app.locals.bucket = new GridFSBucket(db, {
            bucketName: 'images'
        });

        console.log('GridFS 初始化成功');
    })
    .catch(err => console.log('MongoDB 连接失败:', err));

// 用户模型
const UserSchema = new mongoose.Schema({
    username: { type: String, required: true, unique: true },
    avatar: { type: String, required: false },
    phone: { type: String, required: true, unique: true },
    password: { type: String, required: true },
    school: { type: mongoose.Schema.Types.ObjectId, ref: 'School', required: false },
    clubs: { type: [String], required: false }, // 注意：这里存储的是 Club 的 _id 字符串列表
    gender: { type: String, required: false },
    birthday: { type: Date, required: false },
    registration_time: { type: Date, default: Date.now },
    signature: { type: String, required: false },
    roles: {
        type: [{
            type: String,
            enum: ['user', 'systemAdmin'] // 简化 roles 枚举
        }],
        default: ['user'],
        required: true
    }
});

const User = mongoose.model('User', UserSchema);

// 社团模型
const ClubSchema = new mongoose.Schema({
    clubname: { type: String, required: true },
    description: { type: String },
    clubimg: { type: String },
    clubType: { type: String, required: false }, // 新增：社团类型
    admin: { type: [mongoose.Schema.Types.ObjectId], ref: 'User' },
    school: { type: mongoose.Schema.Types.ObjectId, ref: 'School', required: false }, // 新增：关联学校ID
    createTime: { type: Date, default: Date.now },
    members: [{
        user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
        role: { type: String, default: '成员' }, // 默认角色为 '成员'
        joinTime: { type: Date, default: Date.now }
    }],
    joinApplications: [{
        user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
        realname: { type: String, required: true },
        college: { type: String, required: true },
        class: { type: String, required: true },
        studentId: { type: String, required: true },
        gender: { type: String },
        hobby: { type: String },
        applyTime: { type: Date, default: Date.now },
        status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'pending' },
        reason: { type: String },
        rejectReason: { type: String }
    }],
    exitApplications: [{
        user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
        applyTime: { type: Date, default: Date.now },
        status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'pending' },
        reason: { type: String },
        rejectReason: { type: String }
    }]
});

const Club = mongoose.model('Club', ClubSchema);

// 新增：社团创建申请模型
const ClubApplicationSchema = new mongoose.Schema({
    applicantId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
    schoolId: { type: mongoose.Schema.Types.ObjectId, ref: 'School', required: true },
    clubname: { type: String, required: true },
    clubType: { type: String, required: true },
    description: { type: String, required: true },
    reason: { type: String, required: true },
    logo: { type: String, required: false }, // 存储 GridFS 文件 ID
    status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'pending' },
    applyTime: { type: Date, default: Date.now },
    rejectReason: { type: String, required: false }
});

const ClubApplication = mongoose.model('ClubApplication', ClubApplicationSchema);

// 新增：社团解散申请模型
const ClubDissolutionApplicationSchema = new mongoose.Schema({
    applicantId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true }, // 申请人ID
    clubId: { type: mongoose.Schema.Types.ObjectId, ref: 'Club', required: true },     // 要解散的社团ID
    schoolId: { type: mongoose.Schema.Types.ObjectId, ref: 'School', required: true }, // 所属学校ID
    reason: { type: String, required: true },                                          // 解散理由
    status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'pending' }, // 申请状态
    applyTime: { type: Date, default: Date.now },                                       // 申请时间
    rejectReason: { type: String, required: false }                                     // 拒绝理由
});

const ClubDissolutionApplication = mongoose.model('ClubDissolutionApplication', ClubDissolutionApplicationSchema);

// 帖子模型
const PostSchema = new mongoose.Schema({
    title: { type: String, required: true },
    description: { type: String, required: true },
    image: { type: String, required: false }, // 存储GridFS中的文件ID
    authorId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
    authorimg: { type: String, required: false },
    author: { type: String, required: false },
    // likes: { type: Number, default: 0 }, // 移除旧的 likes 字段
    likedBy: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // 新增：点赞用户列表
    comments: [{
        userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
        username: { type: String, required: true },
        avatar: { type: String }, // 头像 ID (可选)
        text: { type: String, required: true },
        createdAt: { type: Date, default: Date.now }
    }],
    // 发布范围相关字段
    publishToHomepage: { type: Boolean, default: true }, // 是否发布到首页
    publishToSchool: { type: mongoose.Schema.Types.ObjectId, ref: 'School', required: false }, // 发布到哪个学校
    publishToClubs: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Club' }], // 发布到哪些社团
    clubId: { type: mongoose.Schema.Types.ObjectId, ref: 'Club', required: false },
    createdAt: { type: Date, default: Date.now }
});

const Post = mongoose.model('Post', PostSchema);

// 活动模型
const ActivitySchema = new mongoose.Schema({
    activename: { type: String, required: true },
    activetime: { type: String, required: true },
    activeadd: { type: String, required: true },
    description: { type: String },
    club: { type: mongoose.Schema.Types.ObjectId, ref: 'Club', required: true },
    createdAt: { type: Date, default: Date.now },
    endTime: { type: Date },
    status: { type: String, enum: ['upcoming', 'ongoing', 'completed'], default: 'upcoming' },
    maxParticipants: { type: Number, default: 50 }, // 人数上限
    poster: { type: String }, // 活动海报
    // 活动报名
    participants: [
        {
            userId: { type: String, required: true }, // 用户ID
            user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }, // 用户引用
            username: { type: String }, // 用户名
            realName: { type: String }, // 真实姓名
            studentId: { type: String }, // 学号
            contact: { type: String }, // 联系方式
            remark: { type: String }, // 备注
            avatar: { type: String }, // 头像
            registerTime: { type: Date, default: Date.now }, // 报名时间
            status: { type: String, enum: ['pending', 'approved', 'rejected'], default: 'approved' } // 报名状态，默认为已批准
        }
    ]
});

const Activity = mongoose.model('Activity', ActivitySchema);

// 学校模型
const SchoolSchema = new mongoose.Schema({
    id: { type: Number, required: true },
    name: { type: String, required: true },
    address: { type: String, required: false }, // 学校地址
    logo: { type: String, required: false }, // 学校校徽（存储GridFS中的文件ID）
    description: { type: String, required: false }, // 学校简介
    establishedDate: { type: Date, required: false }, // 成立日期
    website: { type: String, required: false }, // 官方网站
    contactPhone: { type: String, required: false }, // 联系电话
    contactEmail: { type: String, required: false }, // 联系邮箱
    clubs: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Club' }], // 该学校的所有社团
    users: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // 该学校的所有用户
    posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }], // 该学校的所有帖子
    admin: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }], // 该学校的所有管理员
    createdAt: { type: Date, default: Date.now },
    updatedAt: { type: Date, default: Date.now }
});

// 添加更新时间自动更新的中间件
SchoolSchema.pre('save', function (next) {
    this.updatedAt = Date.now();
    next();
});
// 中间件：验证用户 Token
const authenticateToken = (req, res, next) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }
    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        req.userId = decoded.id; // 将 userId 附加到请求对象
        next();
    } catch (error) {
        console.error('Token 验证失败:', error);
        return res.status(403).json({ message: '无效的 Token' });
    }
};
const School = mongoose.model('School', SchoolSchema);

// 设置内存存储用于临时存储上传的文件
const storage = multer.memoryStorage();
const upload = multer({ storage });

// 注册用户
app.post('/register', async (req, res) => {
    const { username, password, phone, roles } = req.body;
    const hashedPassword = await bcrypt.hash(password, 10); // 加密密码
    const newUser = new User({ username, password: hashedPassword, phone, roles: ['user'] });
    try {
        await newUser.save();
        res.status(201).json({ message: '用户注册成功' });
    } catch (error) {
        console.error('Error registering user:', error);
        res.status(500).json({ message: '注册失败' });
    }
});

// 登录用户
app.post('/login', async (req, res) => {
    const { phone, password } = req.body;
    try {
        const user = await User.findOne({ phone });
        if (!user) {
            return res.status(400).json({ message: '用户不存在' });
        }
        const isMatch = await bcrypt.compare(password, user.password);
        if (!isMatch) {
            return res.status(400).json({ message: '密码错误' });
        }
        // 生成 JWT 令牌
        const token = jwt.sign({ id: user._id }, 'your_jwt_secret', { expiresIn: '30d' });
        res.status(200).json({ token, user: { id: user._id, username: user.username, phone: user.phone, avatar: user.avatar, roles: user.roles } });
    } catch (error) {
        console.error('Error logging in:', error);
        res.status(500).json({ message: '登录失败' });
    }
});
// 获取图片
app.get('/uploads/:imageId', async (req, res) => {
    try {
        const imageId = req.params.imageId;

        // 检查是否是有效的ObjectId
        if (!ObjectId.isValid(imageId)) {
            return res.status(400).json({ message: '无效的图片ID' });
        }

        const bucket = app.locals.bucket;
        const _id = new ObjectId(imageId);

        // 检查文件是否存在
        const files = await bucket.find({ _id }).toArray();
        if (!files.length) {
            return res.status(404).json({ message: '图片未找到' });
        }

        // 设置正确的内容类型
        res.set('Content-Type', files[0].contentType);

        // 创建下载流并管道到响应
        const downloadStream = bucket.openDownloadStream(_id);
        downloadStream.pipe(res);

    } catch (error) {
        console.error('Error fetching image:', error);
        res.status(500).json({ message: '获取图片失败' });
    }
});
//获取动态（支持按范围筛选）
app.get('/posts', async (req, res) => {
    try {
        const limit = parseInt(req.query.limit) || 50;
        const skip = parseInt(req.query.skip) || 0;
        const { scope, schoolId, clubId } = req.query;
        const currentUserId = req.userId; // 获取当前登录用户 ID

        // 构建查询条件
        let query = {};

        if (scope === 'homepage') {
            query.publishToHomepage = true;
        } else if (scope === 'school' && schoolId) {
            query.publishToSchool = schoolId;
        } else if (scope === 'club' && clubId) {
            query.publishToClubs = { $in: [clubId] };
        } else if (!scope) {
            query.publishToHomepage = true;
        }

        console.log('查询条件:', query);

        // 查找帖子并填充评论用户信息
        const posts = await Post.find(query)
            .populate('comments.userId', 'username avatar') // 填充评论者的用户名和头像ID
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit)
            .lean(); // 使用 lean() 获取普通 JS 对象，方便修改

        // 为每个帖子添加点赞数和当前用户的点赞状态
        const processedPosts = posts.map(post => {
            const likes = post.likedBy?.length || 0;
            const isLikedByCurrentUser = post.likedBy?.some(id => id.equals(currentUserId)) || false;
            // 格式化评论，添加头像 URL
            const formattedComments = post.comments.map(comment => ({
                ...comment,
                avatarUrl: comment.userId?.avatar ? `http://localhost:5000/uploads/${comment.userId.avatar}` : null,
                // 可以在这里保留或移除原始的 userId 对象
                // userId: comment.userId._id // 如果只需要 ID
            }));

            return {
                ...post,
                likes: likes, // 添加计算后的点赞数
                isLiked: isLikedByCurrentUser, // 添加当前用户的点赞状态
                comments: formattedComments // 使用格式化后的评论
            };
        });

        res.status(200).json(processedPosts);
    } catch (error) {
        console.error('Error fetching posts:', error);
        res.status(500).json({ message: '获取帖子失败' });
    }
});

// 获取学校数据
app.get('/school', async (req, res) => {
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;

        if (req.query.page && req.query.limit) {
            // 分页请求
            const total = await School.countDocuments();
            const schools = await School.find()
                .sort({ id: 1 })
                .skip(skip)
                .limit(limit);

            return res.status(200).json({
                schools,
                pagination: {
                    total,
                    page,
                    totalPages: Math.ceil(total / limit)
                }
            });
        } else {
            // 获取所有学校（用于搜索等场景）
            const schools = await School.find();
            return res.status(200).json(schools);
        }
    } catch (error) {
        console.error('获取学校数据失败:', error);
        res.status(500).json({ message: '获取学校数据失败' });
    }
});

// 获取单个学校信息
app.get('/school/:id', async (req, res) => {
    try {
        const schoolId = req.params.id;

        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        const school = await School.findById(schoolId);

        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        res.status(200).json(school);
    } catch (error) {
        console.error('获取学校信息失败:', error);
        res.status(500).json({ message: '获取学校信息失败' });
    }
});

// 向学校添加用户
app.put('/school/:id/add-user', async (req, res) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    try {
        // 验证token
        const decoded = jwt.verify(token, 'your_jwt_secret');

        const schoolId = req.params.id;
        const { userId } = req.body;

        if (!mongoose.Types.ObjectId.isValid(schoolId) || !mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的学校ID或用户ID' });
        }

        // 查找学校
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 检查用户是否已经在学校列表中
        if (school.users.includes(userId)) {
            return res.status(200).json({ message: '用户已经属于该学校' });
        }

        // 添加用户到学校
        school.users.push(userId);
        await school.save();

        res.status(200).json({ message: '用户成功添加到学校' });
    } catch (error) {
        console.error('向学校添加用户失败:', error);
        res.status(500).json({ message: '向学校添加用户失败' });
    }
});

// 添加学校
app.post('/school', upload.single('logo'), async (req, res) => {
    try {
        const { name, address } = req.body;
        let logoId = null;

        // 如果有上传logo，将其存储到 GridFS
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex');

            // 创建上传流
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });

            // 写入文件数据
            uploadStream.write(req.file.buffer);
            uploadStream.end();

            // 等待上传完成
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    logoId = uploadStream.id.toString(); // 存储文件ID
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 生成新ID (获取最大ID并加1)
        const schools = await School.find().sort({ id: -1 }).limit(1);
        const nextId = schools.length > 0 ? schools[0].id + 1 : 1;

        const newSchool = new School({
            id: nextId,
            name,
            address,
            logo: logoId
        });

        await newSchool.save();
        res.status(201).json(newSchool);
    } catch (error) {
        console.error('添加学校失败:', error);
        res.status(500).json({ message: '添加学校失败' });
    }
});

// 更新学校
app.put('/school/:id', upload.single('logo'), async (req, res) => {
    try {
        const schoolId = req.params.id; // 获取 MongoDB _id
        const { name, address, description, establishedDate, website, contactPhone, contactEmail } = req.body;

        // 验证ID有效性
        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        // 使用 findById 查找学校
        const school = await School.findById(schoolId);

        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 处理 logo 上传逻辑 (如果需要)
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex');
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });
            uploadStream.write(req.file.buffer);
            uploadStream.end();
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    // 如果之前有logo，先删除旧的
                    if (school.logo) {
                        bucket.delete(new ObjectId(school.logo)).catch(err => console.error("删除旧logo失败:", err));
                    }
                    school.logo = uploadStream.id.toString(); // 更新logo ID
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 更新其他字段 (检查 undefined 避免意外清空)
        if (name !== undefined) school.name = name;
        if (address !== undefined) school.address = address;
        if (description !== undefined) school.description = description;
        if (establishedDate !== undefined) school.establishedDate = establishedDate;
        if (website !== undefined) school.website = website;
        if (contactPhone !== undefined) school.contactPhone = contactPhone;
        if (contactEmail !== undefined) school.contactEmail = contactEmail;

        await school.save();
        res.status(200).json(school);
    } catch (error) {
        console.error('更新学校失败:', error);
        res.status(500).json({ message: '更新学校失败' });
    }
});

// 删除学校
app.delete('/school/:id', async (req, res) => {
    try {
        const schoolId = req.params.id; // 获取 MongoDB _id

        // 验证ID有效性
        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        // 使用 findByIdAndDelete 删除学校
        const result = await School.findByIdAndDelete(schoolId);

        if (!result) {
            return res.status(404).json({ message: '学校未找到' });
        }
        res.status(200).json({ message: '学校删除成功' });
    } catch (error) {
        console.error('删除学校失败:', error);
        res.status(500).json({ message: '删除学校失败' });
    }
});

// 获取所有社团（支持分页和搜索）
app.get('/clubs', async (req, res) => {
    try {
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const { search } = req.query; // 获取搜索参数

        // 构建查询条件
        let query = {};
        if (search) {
            // 使用正则表达式进行模糊搜索，忽略大小写
            query.clubname = { $regex: search, $options: 'i' };
            // 如果需要同时搜索描述，可以这样写：
            // query.$or = [
            //     { clubname: { $regex: search, $options: 'i' } },
            //     { description: { $regex: search, $options: 'i' } }
            // ];
        }

        // 计算总数（应用查询条件）
        const total = await Club.countDocuments(query);

        // 查询社团列表（应用查询条件）
        const clubs = await Club.find(query)
            .populate('school', 'name') // 填充学校信息
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit);

        res.status(200).json({
            clubs,
            pagination: {
                total,
                page,
                totalPages: Math.ceil(total / limit)
            }
        });
    } catch (error) {
        console.error('获取社团列表失败:', error);
        res.status(500).json({ message: '获取社团列表失败' });
    }
});

// 根据学校ID获取社团（支持分页）
app.get('/schools/:schoolId/clubs', async (req, res) => {
    try {
        const schoolId = req.params.schoolId;
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;

        // 验证学校ID
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 获取学校的社团列表
        let clubs = [];
        let total = 0;

        // 两种方式查询社团：1. 通过school字段关联 2. 通过学校的clubs数组
        if (school.clubs && school.clubs.length > 0) {
            console.log('通过学校clubs数组查询社团');

            // 直接使用学校的clubs数组（已经是ObjectId类型）
            const clubIds = school.clubs;
            total = clubIds.length;

            // 根据分页参数获取部分社团
            const paginatedIds = clubIds.slice(skip, skip + limit);
            clubs = await Club.find({ _id: { $in: paginatedIds } })
                .sort({ createdAt: -1 });

            console.log(`找到 ${clubs.length} 个社团，通过clubs数组，总数：${total}`);
        } else {
            console.log('通过社团school字段查询社团');
            // 计算总数
            total = await Club.countDocuments({ school: schoolId });

            // 查询社团列表
            clubs = await Club.find({ school: schoolId })
                .sort({ createdAt: -1 })
                .skip(skip)
                .limit(limit);

            console.log(`找到 ${clubs.length} 个社团，通过school字段，总数：${total}`);
        }

        res.status(200).json({
            clubs,
            pagination: {
                total,
                page,
                totalPages: Math.ceil(total / limit)
            }
        });
    } catch (error) {
        console.error('获取学校社团列表失败:', error);
        res.status(500).json({ message: '获取学校社团列表失败', error: error.message });
    }
});

// 获取学校所有社团的活动列表
app.get('/schools/:schoolId/activities', async (req, res) => {
    try {
        const schoolId = req.params.schoolId;
        const limit = parseInt(req.query.limit) || 10;

        // 验证学校ID
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        let clubIds = [];

        // 优先使用学校的clubs数组
        if (school.clubs && school.clubs.length > 0) {
            console.log('通过学校clubs数组查找社团活动');
            clubIds = school.clubs;
        } else {
            // 查找该学校的所有社团ID
            console.log('通过社团school字段查找社团活动');
            const clubs = await Club.find({ school: schoolId }, '_id');
            clubIds = clubs.map(club => club._id);
        }

        console.log(`找到 ${clubIds.length} 个社团ID`);

        // 查询这些社团的活动
        const activities = await Activity.find({ club: { $in: clubIds } })
            .sort({ activetime: 1 }) // 按活动时间排序
            .limit(limit)
            .populate('club', 'clubname'); // 填充社团信息

        console.log(`找到 ${activities.length} 个活动`);

        res.status(200).json(activities);
    } catch (error) {
        console.error('获取学校活动列表失败:', error);
        res.status(500).json({ message: '获取学校活动列表失败', error: error.message });
    }
});

// 获取用户列表
app.get('/users', authenticateToken, async (req, res) => {
    try {
        // --- 权限检查：只有 systemAdmin 可以访问 ---
        const requestingUser = await User.findById(req.userId).select('roles');
        if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
            return res.status(403).json({ message: '权限不足' });
        }
        // --- 权限检查结束 ---

        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const { search, role } = req.query;

        // 构建查询条件
        let query = {};
        if (search) {
            query.$or = [
                { username: { $regex: search, $options: 'i' } },
                { phone: { $regex: search, $options: 'i' } }
            ];
        }
        if (role && role !== 'all') {
            if (role === 'admin') {
                query.roles = 'systemAdmin';
            } else if (role === 'user') {
                query.roles = { $ne: 'systemAdmin' };
            }
        }

        // 计算总数
        const total = await User.countDocuments(query);

        // 查询用户列表 (选择需要的字段 + 填充学校名称)
        const users = await User.find(query)
            .select('username phone roles registration_time avatar school clubs') // 添加 clubs
            .populate('school', 'name')
            .sort({ registration_time: -1 })
            .skip(skip)
            .limit(limit)
            .lean();

        res.status(200).json({
            users: users.map(u => ({ ...u, schoolName: u.school?.name || '未分配' })), // 添加 schoolName 字段
            total,
            pagination: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit)
            }
        });
    } catch (error) {
        console.error('获取用户列表失败:', error);
        res.status(500).json({ message: '获取用户列表失败' });
    }
});

// --- 新增 GET /users/:userId/details 接口 ---
app.get('/users/:userId/details', authenticateToken, async (req, res) => {
    try {
        // --- 权限检查：只有 systemAdmin 可以访问 ---
        const requestingUser = await User.findById(req.userId).select('roles');
        if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
            return res.status(403).json({ message: '权限不足' });
        }
        // --- 权限检查结束 ---

        const { userId } = req.params;

        if (!mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的用户ID' });
        }

        // 查询用户并填充详细信息
        const user = await User.findById(userId)
            .populate('school', 'name') // 填充学校名称
            // .populate('clubs') // 直接填充 clubs 可能返回大量数据，考虑只填充名称或 ID
            .lean(); // 使用 lean

        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 如果需要社团名称列表
        let clubDetails = [];
        if (user.clubs && user.clubs.length > 0) {
            try {
                const clubObjectIds = user.clubs.map(idStr => new mongoose.Types.ObjectId(idStr));
                const clubs = await Club.find({ _id: { $in: clubObjectIds } }).select('clubname').lean();
                clubDetails = clubs;
            } catch (clubError) {
                console.error("获取用户社团详情失败:", clubError);
                // 即使社团信息获取失败，也继续返回用户信息
            }
        }

        // 从 user 对象中移除敏感信息（如果需要）
        delete user.password;

        res.status(200).json({ ...user, clubs: clubDetails }); // 返回包含社团详情的用户信息

    } catch (error) {
        console.error('获取用户详情失败:', error);
        res.status(500).json({ message: '获取用户详情失败' });
    }
});

// --- 更新用户角色接口 (确保在 details 接口之后，或者调整位置) ---
app.put('/users/:userId/role', authenticateToken, async (req, res) => {
    // TODO: 添加管理员权限检查中间件 (更细粒度的)
    try {
        // 检查当前用户是否是 systemAdmin
        const requestingUser = await User.findById(req.userId);
        if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
            return res.status(403).json({ message: '权限不足，只有系统管理员才能修改角色' });
        }

        const { userId } = req.params;
        const { roles } = req.body; // 前端发送的是 roles: ['systemAdmin'] 或 ['user']

        if (!mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的用户ID' });
        }
        if (!Array.isArray(roles) || roles.length === 0 || !['user', 'systemAdmin'].includes(roles[0])) {
            return res.status(400).json({ message: '无效的角色数据' });
        }

        // 查找用户
        const user = await User.findById(userId);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 禁止修改自己的角色
        if (user._id.equals(req.userId)) {
            return res.status(400).json({ message: '不能修改自己的角色' });
        }

        // 更新角色
        user.roles = roles; // 直接替换角色数组
        await user.save();

        res.status(200).json({ message: '用户角色更新成功', user: { _id: user._id, username: user.username, roles: user.roles } }); // 返回部分信息

    } catch (error) {
        console.error('更新用户角色失败:', error);
        res.status(500).json({ message: '更新用户角色失败' });
    }
});

// --- 删除用户接口 (确保在 details 接口之后，或者调整位置) ---
app.delete('/users/:userId', authenticateToken, async (req, res) => {
    // TODO: 添加管理员权限检查中间件 (更细粒度的)
    // 检查当前用户是否是 systemAdmin
    const requestingUser = await User.findById(req.userId);
    if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
        return res.status(403).json({ message: '权限不足，只有系统管理员才能删除用户' });
    }

    try {
        const { userId } = req.params;

        if (!mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的用户ID' });
        }

        // 禁止删除自己
        if (userId === req.userId) {
            return res.status(400).json({ message: '不能删除自己' });
        }

        // 查找并删除用户
        const deletedUser = await User.findByIdAndDelete(userId);
        if (!deletedUser) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // [可选] 删除用户的头像等关联资源
        if (deletedUser.avatar) {
            try {
                const bucket = app.locals.bucket;
                await bucket.delete(new ObjectId(deletedUser.avatar));
                console.log(`已删除用户 ${deletedUser.username} 的头像: ${deletedUser.avatar}`);
            } catch (avatarError) {
                console.error('删除用户头像失败:', avatarError);
            } // 不阻止后续操作
        }

        // [重要] 从关联数据中移除用户引用 (示例：从学校、社团成员、帖子作者等)
        const userIdToRemove = deletedUser._id;

        // 1. 从学校移除
        if (deletedUser.school) {
            await School.updateOne(
                { _id: deletedUser.school },
                { $pull: { users: userIdToRemove, admin: userIdToRemove } } // 从 users 和 admin 移除
            );
        }
        // 2. 从社团成员/管理员移除
        const userClubIds = deletedUser.clubs || [];
        if (userClubIds.length > 0) {
            const clubObjectIds = userClubIds.map(idStr => new mongoose.Types.ObjectId(idStr)); // 转换为 ObjectId
            await Club.updateMany(
                { _id: { $in: clubObjectIds } },
                {
                    $pull: {
                        members: { user: userIdToRemove }, // 从 members 数组移除
                        admin: userIdToRemove,          // 从 admin 数组移除
                        joinApplications: { user: userIdToRemove }, // 从加入申请移除
                        exitApplications: { user: userIdToRemove }  // 从退出申请移除
                    }
                }
            );
        }
        // 3. 处理用户发布的帖子、评论、活动报名等 (根据业务需求决定)
        //    - 将帖子作者置空
        await Post.updateMany({ authorId: userIdToRemove }, { $set: { authorId: null, author: '已注销用户', authorimg: null } });
        //    - 更新评论者信息
        await Post.updateMany({}, { $pull: { comments: { userId: userIdToRemove } } }); // 直接移除该用户的所有评论
        //    - 移除点赞记录
        await Post.updateMany({ likedBy: userIdToRemove }, { $pull: { likedBy: userIdToRemove } });
        //    - 移除活动报名
        await Activity.updateMany({ 'participants.user': userIdToRemove }, { $pull: { participants: { user: userIdToRemove } } });
        //    - [待补充] 处理用户创建的社团申请、解散申请等
        await ClubApplication.deleteMany({ applicantId: userIdToRemove });
        await ClubDissolutionApplication.deleteMany({ applicantId: userIdToRemove });


        res.status(200).json({ message: '用户删除成功' });

    } catch (error) {
        console.error('删除用户失败:', error);
        res.status(500).json({ message: '删除用户失败' });
    }
});

// 获取当前用户信息
app.get('/users/me', async (req, res) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const user = await User.findById(decoded.id);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }
        res.status(200).json(user);
    } catch (error) {
        console.error('Error fetching user info:', error);
        res.status(500).json({ message: '获取用户信息失败' });
    }
});

// 获取用户加入的社团列表
app.get('/users/me/clubs', async (req, res) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const user = await User.findById(decoded.id);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 如果用户没有加入任何社团
        if (!user.clubs || user.clubs.length === 0) {
            return res.status(200).json([]);
        }

        // 获取用户加入的所有社团详情
        const clubs = await Club.find({
            '_id': { $in: user.clubs },
        }).select('_id clubname clubimg description');

        res.status(200).json(clubs);
    } catch (error) {
        console.error('获取用户社团失败:', error);
        res.status(500).json({ message: '获取用户社团失败' });
    }
});

// 发布帖子
app.post('/posts', upload.single('image'), async (req, res) => {
    const { title, description, publishToHomepage, publishToSchool, publishToClubs } = req.body;
    const token = req.headers['authorization']?.split(' ')[1];

    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const user = await User.findById(decoded.id);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        let imageId = null;

        // 如果有上传图片，将其存储到 GridFS
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex');

            // 创建上传流
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });

            // 写入文件数据
            uploadStream.write(req.file.buffer);
            uploadStream.end();

            // 等待上传完成
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    imageId = uploadStream.id.toString(); // 存储文件ID
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 处理发布范围 - 修复首页发布逻辑
        // 只有当明确设置为true时才发布到首页，避免默认发布
        const publishToHomepageValue =
            publishToHomepage === 'true' ||
            publishToHomepage === true ||
            publishToHomepage === '1' ||
            publishToHomepage === 1;

        console.log('发布范围设置：', {
            原始值: publishToHomepage,
            处理后: publishToHomepageValue,
            类型: typeof publishToHomepage
        });

        const postData = {
            title,
            description,
            image: imageId,
            authorId: user._id,
            authorimg: user.avatar || 'src/components/icons/touxiang.png',
            author: user.username,
            publishToHomepage: publishToHomepageValue, // 使用处理后的值
            createdAt: new Date()
        };

        // 如果发布到学校，验证学校ID是否是用户所属学校
        if (publishToSchool && mongoose.Types.ObjectId.isValid(publishToSchool)) {
            // 验证该学校ID是否是用户所属学校
            if (user.school && user.school.toString() === publishToSchool) {
                postData.publishToSchool = new mongoose.Types.ObjectId(publishToSchool);
            } else {
                return res.status(403).json({ message: '只能发布到您所属的学校' });
            }
        }

        // 如果发布到社团，验证社团ID是否是用户加入的社团
        if (publishToClubs) {
            let clubIds = [];
            try {
                clubIds = JSON.parse(publishToClubs);
            } catch (e) {
                return res.status(400).json({ message: '社团ID格式错误' });
            }

            if (Array.isArray(clubIds) && clubIds.length > 0) {
                // 验证这些社团ID是否都是用户加入的社团
                const userClubIds = user.clubs || [];

                // 转换为字符串以便比较
                const userClubIdsStr = userClubIds.map(id => id.toString());

                // 检查每个提交的社团ID是否在用户的社团列表中
                const invalidClubs = clubIds.filter(id => !userClubIdsStr.includes(id.toString()));

                if (invalidClubs.length > 0) {
                    return res.status(403).json({
                        message: '只能发布到您加入的社团',
                        invalidClubs
                    });
                }

                // 转换为ObjectId
                postData.publishToClubs = clubIds.map(id => new mongoose.Types.ObjectId(id));
            }
        }

        // 确保至少有一个发布范围
        if (!postData.publishToHomepage &&
            !postData.publishToSchool &&
            (!postData.publishToClubs || postData.publishToClubs.length === 0)) {
            return res.status(400).json({ message: '请至少选择一个发布范围' });
        }

        const newPost = new Post(postData);
        await newPost.save();

        // 如果发布到学校，将帖子ID添加到学校的posts数组
        if (postData.publishToSchool) {
            const school = await School.findById(postData.publishToSchool);
            if (school) {
                school.posts.push(newPost._id);
                await school.save();
            }
        }

        res.status(201).json(newPost);
    } catch (error) {
        console.error('Error saving post:', error);
        res.status(500).send('Internal Server Error');
    }
});

// 获取用户发布的帖子
app.get('/users/:id/posts', async (req, res) => {
    try {
        const posts = await Post.find({ authorId: req.params.id });
        res.status(200).json(posts);
    } catch (error) {
        console.error('Error fetching user posts:', error);
        res.status(500).json({ message: '获取用户帖子失败' });
    }
});

// 更新用户信息
app.put('/users/me', async (req, res) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const user = await User.findById(decoded.id);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        Object.assign(user, req.body);
        await user.save();
        res.status(200).json(user);
    } catch (error) {
        console.error('Error updating user info:', error);
        res.status(500).json({ message: '更新用户信息失败' });
    }
});

// 上传用户头像
app.post('/users/me/avatar', upload.single('avatar'), async (req, res) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }

    if (!req.file) {
        return res.status(400).json({ message: '请上传头像文件' });
    }

    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const user = await User.findById(decoded.id);

        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 创建文件存储桶
        const bucket = app.locals.bucket;
        const uniqueFilename = crypto.randomBytes(16).toString('hex') + '_avatar';

        // 创建上传流
        const uploadStream = bucket.openUploadStream(uniqueFilename, {
            contentType: req.file.mimetype
        });

        // 写入文件数据
        uploadStream.write(req.file.buffer);
        uploadStream.end();

        // 等待上传完成
        await new Promise((resolve, reject) => {
            uploadStream.on('finish', () => {
                // 更新用户头像ID
                user.avatar = uploadStream.id.toString();
                resolve();
            });
            uploadStream.on('error', reject);
        });

        // 保存更新后的用户信息
        await user.save();

        res.status(200).json({
            message: '头像上传成功',
            avatar: user.avatar
        });
    } catch (error) {
        console.error('上传头像失败:', error);
        res.status(500).json({ message: '上传头像失败', error: error.message });
    }
});

// 添加社团
app.post('/clubs', upload.single('clubimg'), async (req, res) => {
    try {
        const { clubname, description, school } = req.body;

        // 验证学校ID
        if (!mongoose.Types.ObjectId.isValid(school)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        // 查找学校
        const schoolDoc = await School.findById(school);
        if (!schoolDoc) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 处理上传的社团图片
        let clubimgId = null;
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex');

            // 创建上传流
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });

            // 写入文件数据
            uploadStream.write(req.file.buffer);
            uploadStream.end();

            // 等待上传完成
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    clubimgId = uploadStream.id.toString();
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 创建新社团
        const newClub = new Club({
            clubname,
            clubimg: clubimgId,
            description,
            school,
            createdAt: new Date()
        });

        // 保存社团
        const savedClub = await newClub.save();

        // 将社团ID添加到学校的clubs数组中
        if (!schoolDoc.clubs) {
            schoolDoc.clubs = [];
        }
        schoolDoc.clubs.push(savedClub._id);
        await schoolDoc.save();

        res.status(201).json(savedClub);
    } catch (error) {
        console.error('创建社团失败:', error);
        res.status(500).json({ message: '创建社团失败', error: error.message });
    }
});

// 获取学校帖子
app.get('/schools/:schoolId/posts', async (req, res) => {
    try {
        const { schoolId } = req.params;
        const limit = parseInt(req.query.limit) || 20;
        const skip = parseInt(req.query.skip) || 0;

        // 验证学校ID
        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        // 查询发布到该学校的帖子，确保明确设置了发布到该学校
        const query = { publishToSchool: schoolId };
        console.log('获取学校帖子查询条件:', query);

        const posts = await Post.find(query)
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit);

        res.status(200).json(posts);
    } catch (error) {
        console.error('获取学校帖子失败:', error);
        res.status(500).json({ message: '获取学校帖子失败' });
    }
});

// 获取社团帖子
app.get('/clubs/:clubId/posts', async (req, res) => {
    try {
        const { clubId } = req.params;
        const limit = parseInt(req.query.limit) || 20;
        const skip = parseInt(req.query.skip) || 0;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查询发布到该社团的帖子
        const posts = await Post.find({ publishToClubs: { $in: [clubId] } })
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit);

        res.status(200).json(posts);
    } catch (error) {
        console.error('获取社团帖子失败:', error);
        res.status(500).json({ message: '获取社团帖子失败' });
    }
});

// 新增：获取社团拥有的帖子 (根据 clubId)
app.get('/clubs/:clubId/owned-posts', async (req, res) => {
    try {
        const { clubId } = req.params;
        const limit = parseInt(req.query.limit) || 20;
        const skip = parseInt(req.query.skip) || 0;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查询 clubId 匹配的帖子
        const posts = await Post.find({ clubId: clubId })
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit);

        res.status(200).json(posts);
    } catch (error) {
        console.error('获取社团所属帖子失败:', error);
        res.status(500).json({ message: '获取社团所属帖子失败' });
    }
});

// 获取单个社团信息
app.get('/clubs/:id', async (req, res) => {
    try {
        const clubId = req.params.id;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查询社团信息
        const club = await Club.findById(clubId);

        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        res.status(200).json(club);
    } catch (error) {
        console.error('获取社团信息失败:', error);
        res.status(500).json({ message: '获取社团信息失败' });
    }
});

// 获取社团活动
app.get('/clubs/:id/activities', async (req, res) => {
    try {
        const clubId = req.params.id;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查询该社团的活动
        const activities = await Activity.find({ club: clubId })
            .sort({ activetime: 1 }); // 按活动时间排序

        res.status(200).json(activities);
    } catch (error) {
        console.error('获取社团活动失败:', error);
        res.status(500).json({ message: '获取社团活动失败' });
    }
});

// 获取社团成员
app.get('/clubs/:id/members', async (req, res) => {
    try {
        const clubId = req.params.id;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查询社团信息，并填充成员的用户信息 (选择需要的字段)
        const club = await Club.findById(clubId).populate('members.user', 'username avatar');

        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 获取社团成员信息
        const members = club.members || [];

        // 格式化返回的成员数据
        const formattedMembers = members.map(member => {
            if (!member.user) {
                console.warn('成员记录缺少用户信息:', member);
                return null; // 或者返回一个默认结构
            }
            // 构建返回的成员对象，包含所有需要展示的字段
            return {
                id: member.user._id, // 使用用户文档的_id作为成员列表的主键
                name: member.realname || member.user.username, // 优先用真实姓名，否则用用户名
                username: member.user.username,
                // 构建完整的头像URL或返回相对路径由前端处理
                avatar: member.user.avatar ? `http://localhost:5000/uploads/${member.user.avatar}` : null,
                role: member.role,
                joinTime: member.joinTime,
                // 添加从申请同步的字段
                studentId: member.studentId || 'N/A', // 如果没有提供，显示 N/A
                college: member.college || 'N/A',
                className: member.className || 'N/A',
                gender: member.gender || 'N/A',
                hobbies: member.hobbies || 'N/A',
                // 判断是否为管理员
                isAdmin: club.admin && club.admin.some(adminId =>
                    adminId.toString() === member.user._id.toString()
                )
            };
        }).filter(member => member !== null); // 过滤掉用户信息缺失的记录

        res.status(200).json(formattedMembers);
    } catch (error) {
        console.error('获取社团成员失败:', error);
        res.status(500).json({ message: '获取社团成员失败' });
    }
});

// 提交社团加入申请
app.post('/clubs/:id/applications', async (req, res) => {
    try {
        const clubId = req.params.id;
        const { userId, username, name, college, className, studentId, gender, hobbies, reason, applyTime, clubid } = req.body;

        console.log('收到申请数据:', req.body);

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找用户
        const user = await User.findById(userId);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 检查用户是否已经是社团成员
        const isAlreadyMember = club.members.some(member => {
            if (!member.user) return false;
            return member.user.toString() === userId;
        });
        if (isAlreadyMember) {
            return res.status(400).json({ message: '您已经是社团成员' });
        }

        // 检查用户是否已有待处理的申请
        const hasPendingApplication = club.joinApplications.some(app =>
            app.user.toString() === userId && app.status === 'pending'
        );
        if (hasPendingApplication) {
            return res.status(400).json({ message: '您已有待处理的申请' });
        }

        // 创建新的申请
        const newApplication = {
            user: userId,
            realname: name,
            college: college,
            class: className,
            studentId: studentId,
            gender: gender,
            hobby: hobbies || '',
            applyTime: applyTime || new Date(),
            status: 'pending',
            reason: reason
        };

        console.log('准备添加申请:', newApplication);

        // 添加到社团的申请列表
        club.joinApplications.push(newApplication);

        // 确保club有clubid字段，如果前端传递了clubid则使用，否则使用默认逻辑
        if (clubid && !club.clubid) {
            club.clubid = clubid;
        } else if (!club.clubid) {
            // 如果没有clubid，生成一个默认值
            club.clubid = clubId.toString();
        }

        await club.save();

        res.status(201).json({
            message: '申请提交成功',
            application: newApplication
        });
    } catch (error) {
        console.error('提交社团申请失败:', error);
        res.status(500).json({ message: '提交社团申请失败', error: error.message });
    }
});

// 获取社团申请列表
app.get('/clubs/:id/applications', async (req, res) => {
    try {
        const clubId = req.params.id;
        const applicationType = req.query.type || 'join'; // 'join' 或 'exit'

        console.log(`获取社团申请列表 - clubId: ${clubId}, type: ${applicationType}`);

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            console.error(`无效的社团ID: ${clubId}`);
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            console.error(`社团未找到: ${clubId}`);
            return res.status(404).json({ message: '社团未找到' });
        }

        console.log(`已找到社团: ${club.clubname || clubId}`);

        // 根据类型获取申请列表
        let applications = [];
        if (applicationType === 'join') {
            applications = club.joinApplications || [];
            console.log(`找到 ${applications.length} 个加入申请`);
        } else if (applicationType === 'exit') {
            applications = club.exitApplications || [];
            console.log(`找到 ${applications.length} 个退出申请`);
        }

        // 检查和记录申请数据的_id字段
        let missingIdCount = 0;
        applications.forEach((app, index) => {
            if (!app._id) {
                missingIdCount++;
                console.error(`申请 #${index} 缺少_id字段`);
            }
        });

        if (missingIdCount > 0) {
            console.error(`警告: ${missingIdCount}个申请缺少_id字段`);
        }

        // 获取用户信息
        const populatedApplications = [];
        for (const app of applications) {
            if (app.user) {
                try {
                    const user = await User.findById(app.user);
                    if (user) {
                        populatedApplications.push({
                            _id: app._id.toString(), // 确保_id字段存在并转换为字符串
                            userId: user._id,
                            username: user.username,
                            name: app.realname || user.username,
                            college: app.college, // 在现有模型中，class字段存储的是学院信息
                            className: app.class,
                            studentId: app.studentId,
                            gender: app.gender,
                            hobbies: app.hobby,
                            avatar: user.avatar ? `http://localhost:5000/uploads/${user.avatar}` : null,
                            applyTime: app.applyTime,
                            status: app.status,
                            reason: app.reason,
                            rejectReason: app.rejectReason
                        });
                    } else {
                        console.error(`未找到用户: ${app.user}`);
                    }
                } catch (err) {
                    console.error('获取申请用户详情失败:', err);
                }
            } else {
                console.error(`申请缺少用户ID字段: ${app._id}`);
            }
        }

        console.log(`返回 ${populatedApplications.length} 个已处理的申请`);
        res.status(200).json(populatedApplications);
    } catch (error) {
        console.error('获取社团申请列表失败:', error);
        res.status(500).json({ message: '获取社团申请列表失败', error: error.message });
    }
});

// 处理社团申请（通过/拒绝）
app.put('/clubs/:clubId/applications/:applicationId', async (req, res) => {
    try {
        const { clubId, applicationId } = req.params;
        const { status, rejectReason } = req.body;

        console.log(`处理申请 - clubId: ${clubId}, applicationId: ${applicationId}, status: ${status}`);

        // 验证参数
        if (!['approved', 'rejected'].includes(status)) {
            console.error(`无效的状态值: ${status}`);
            return res.status(400).json({ message: '无效的状态值' });
        }

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            console.error(`无效的社团ID: ${clubId}`);
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            console.error(`社团未找到: ${clubId}`);
            return res.status(404).json({ message: '社团未找到' });
        }

        console.log(`已找到社团: ${club.clubname || clubId}`);
        console.log(`处理申请ID: ${applicationId}`);

        // 在加入申请中查找
        let application = null;
        let appType = '';
        let joinAppIndex = -1;
        let exitAppIndex = -1;

        // 先检查加入申请
        if (club.joinApplications && club.joinApplications.length > 0) {
            joinAppIndex = club.joinApplications.findIndex(app => {
                if (!app._id) {
                    console.warn('警告: 申请缺少_id字段');
                    return false;
                }
                const appIdStr = app._id.toString();
                const match = appIdStr === applicationId;
                if (match) {
                    console.log(`在加入申请中找到匹配ID: ${appIdStr}`);
                }
                return match;
            });
        } else {
            console.log('社团没有加入申请');
        }

        if (joinAppIndex !== -1) {
            application = club.joinApplications[joinAppIndex];
            appType = 'join';
            console.log('找到加入申请');
        } else {
            // 再检查退出申请
            if (club.exitApplications && club.exitApplications.length > 0) {
                exitAppIndex = club.exitApplications.findIndex(app => {
                    if (!app._id) {
                        console.warn('警告: 申请缺少_id字段');
                        return false;
                    }
                    const appIdStr = app._id.toString();
                    const match = appIdStr === applicationId;
                    if (match) {
                        console.log(`在退出申请中找到匹配ID: ${appIdStr}`);
                    }
                    return match;
                });
            } else {
                console.log('社团没有退出申请');
            }

            if (exitAppIndex !== -1) {
                application = club.exitApplications[exitAppIndex];
                appType = 'exit';
                console.log('找到退出申请');
            } else {
                console.error(`申请未找到: ${applicationId}`);
                return res.status(404).json({ message: '申请未找到' });
            }
        }

        // 如果申请已经处理，返回错误
        if (application.status !== 'pending') {
            console.error(`申请已处理，当前状态: ${application.status}`);
            return res.status(400).json({ message: '该申请已处理' });
        }

        console.log(`更新申请状态为: ${status}`);

        // 更新申请状态
        application.status = status;
        if (status === 'rejected' && rejectReason) {
            application.rejectReason = rejectReason;
            console.log(`设置拒绝原因: ${rejectReason}`);
        }

        // 如果是批准加入申请，将用户添加到社团成员
        if (status === 'approved' && appType === 'join') {
            console.log('处理加入申请通过逻辑');

            if (!application.user) {
                console.error('申请缺少用户ID字段');
                return res.status(400).json({ message: '申请数据不完整，缺少用户ID' });
            }

            // 确保用户不是已经是社团成员
            const isAlreadyMember = club.members.some(member => {
                if (!member.user) return false;
                return member.user.toString() === application.user.toString();
            });

            if (isAlreadyMember) {
                console.log(`用户已是社团成员: ${application.user}`);
            } else {
                // 添加用户到社团成员列表
                console.log(`添加用户到社团成员: ${application.user}`);
                club.members.push({
                    user: application.user,
                    role: '成员',
                    joinTime: new Date()
                });

                // 找到用户，将社团ID添加到用户的社团列表
                try {
                    const user = await User.findById(application.user);
                    if (user) {
                        console.log(`更新用户的社团列表: ${user.username}`);
                        if (!user.clubs) {
                            user.clubs = [];
                        }
                        if (!user.clubs.includes(clubId)) {
                            user.clubs.push(clubId);
                            await user.save();
                            console.log('用户社团列表已更新');
                        } else {
                            console.log('用户已在社团列表中');
                        }
                    } else {
                        console.error(`未找到用户: ${application.user}`);
                    }
                } catch (userError) {
                    console.error('更新用户社团列表失败:', userError);
                }
            }
        }

        // 如果是批准退出申请，将用户从社团成员移除
        if (status === 'approved' && appType === 'exit') {
            console.log('处理退出申请通过逻辑');

            if (!application.user) {
                console.error('申请缺少用户ID字段');
                return res.status(400).json({ message: '申请数据不完整，缺少用户ID' });
            }

            // 从成员列表中移除用户
            const oldMemberCount = club.members.length;
            club.members = club.members.filter(member => {
                if (!member.user) return true;
                return member.user.toString() !== application.user.toString();
            });
            console.log(`从成员列表移除用户，移除前: ${oldMemberCount}, 移除后: ${club.members.length}`);

            // 如果用户是管理员，也从管理员列表中移除
            if (club.admins && club.admins.includes(application.user)) {
                const oldAdminCount = club.admins.length;
                club.admins = club.admins.filter(adminId => {
                    return adminId.toString() !== application.user.toString();
                });
                console.log(`从管理员列表移除用户，移除前: ${oldAdminCount}, 移除后: ${club.admins.length}`);
            }

            // 更新用户的社团列表
            try {
                const user = await User.findById(application.user);
                if (user && user.clubs) {
                    console.log(`更新用户的社团列表: ${user.username}`);
                    const oldUserClubCount = user.clubs.length;
                    user.clubs = user.clubs.filter(id => id.toString() !== clubId);
                    console.log(`从用户社团列表移除，移除前: ${oldUserClubCount}, 移除后: ${user.clubs.length}`);
                    await user.save();
                    console.log('用户社团列表已更新');
                } else if (user) {
                    console.log('用户没有社团列表');
                } else {
                    console.error(`未找到用户: ${application.user}`);
                }
            } catch (userError) {
                console.error('更新用户社团列表失败:', userError);
            }
        }

        // 保存更改
        console.log('保存社团变更');
        await club.save();
        console.log('社团变更已保存');

        res.status(200).json({
            message: `申请${status === 'approved' ? '通过' : '拒绝'}成功`,
            application
        });
    } catch (error) {
        console.error('处理社团申请失败:', error);
        res.status(500).json({ message: '处理社团申请失败', error: error.message });
    }
});

// 添加社团成员
app.post('/clubs/:id/members', async (req, res) => {
    try {
        const clubId = req.params.id;
        const { userId, username, name, studentId, college, className, gender, hobbies, avatar, role, joinTime } = req.body;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 验证用户ID
        if (!mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的用户ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找用户
        const user = await User.findById(userId);
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 检查用户是否已经是社团成员
        const isAlreadyMember = club.members.some(member =>
            member.user.toString() === userId
        );
        if (isAlreadyMember) {
            return res.status(400).json({ message: '该用户已经是社团成员' });
        }

        // 创建新成员记录
        const newMember = {
            user: userId,
            role: role || '成员',
            joinTime: joinTime || new Date()
        };

        // 添加成员
        club.members.push(newMember);

        // 将社团ID添加到用户的社团列表
        if (!user.clubs) {
            user.clubs = [];
        }
        if (!user.clubs.includes(clubId)) {
            user.clubs.push(clubId);
            await user.save();
        }

        // 保存社团变更
        await club.save();

        res.status(201).json({
            message: '成员添加成功',
            member: {
                _id: newMember._id,
                userId: user._id,
                username: user.username,
                name: name || user.username,
                studentId,
                college,
                className,
                gender,
                hobbies,
                avatar: user.avatar ? `http://localhost:5000/uploads/${user.avatar}` : null,
                role: newMember.role,
                joinTime: newMember.joinTime
            }
        });
    } catch (error) {
        console.error('添加社团成员失败:', error);
        res.status(500).json({ message: '添加社团成员失败', error: error.message });
    }
});

// 更新社团成员角色
app.put('/clubs/:clubId/members/:memberId', async (req, res) => {
    try {
        console.log("更新社团成员角色", req.params)
        const { clubId, memberId } = req.params;
        const { role } = req.body;
        console.log(role, "更新后的角色")
        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找成员
        const memberIndex = club.members.findIndex(m => {
            if (!m.user) return false;
            return m.user.toString() === memberId;
        });
        console.log(memberIndex, "成员索引")
        if (memberIndex === -1) {
            return res.status(404).json({ message: '成员未找到' });
        }

        console.log(club.members[memberIndex], "更新前的成员")
        // 更新成员角色
        club.members[memberIndex].role = role;
        await club.save();

        res.status(200).json({
            message: '成员角色更新成功',
            member: club.members[memberIndex]
        });
    } catch (error) {
        console.error('更新成员角色失败:', error);
        res.status(500).json({ message: '更新成员角色失败', error: error.message });
    }
});

// 移除社团成员
app.delete('/clubs/:clubId/members/:memberId', async (req, res) => {
    try {
        const { clubId, memberId } = req.params;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找成员
        const memberIndex = club.members.findIndex(m => {
            if (!m.user) return false;
            return m.user.toString() === memberId;
        });
        if (memberIndex === -1) {
            return res.status(404).json({ message: '成员未找到' });
        }

        // 获取用户ID
        const userId = club.members[memberIndex].user;

        // 从成员列表中移除
        club.members.splice(memberIndex, 1);

        // 如果是管理员，从管理员列表移除
        if (club.admins && club.admins.includes(userId)) {
            club.admins = club.admins.filter(adminId => adminId.toString() !== userId.toString());
        }

        // 从用户的社团列表中移除
        const user = await User.findById(userId);
        if (user && user.clubs) {
            user.clubs = user.clubs.filter(id => id.toString() !== clubId);
            await user.save();
        }

        // 保存社团变更
        await club.save();

        res.status(200).json({ message: '成员移除成功' });
    } catch (error) {
        console.error('移除社团成员失败:', error);
        res.status(500).json({ message: '移除社团成员失败', error: error.message });
    }
});

// 设置社团管理员
app.put('/clubs/:clubId/admins', async (req, res) => {
    try {
        const { clubId } = req.params;
        const { userId } = req.body;

        // 验证社团ID和用户ID
        if (!mongoose.Types.ObjectId.isValid(clubId) || !mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 检查用户是否是社团成员
        const isMember = club.members.some(m => {
            if (!m.user) return false;
            return m.user.toString() === userId;
        });
        if (!isMember) {
            return res.status(400).json({ message: '该用户不是社团成员' });
        }

        // 确保admins数组存在
        if (!club.admins) {
            club.admins = [];
        }

        // 检查用户是否已经是管理员
        const isAdmin = club.admins.some(adminId => adminId.toString() === userId);
        if (isAdmin) {
            return res.status(400).json({ message: '该用户已经是管理员' });
        }

        // 添加为管理员
        club.admins.push(userId);

        // 找到用户并添加clubAdmin角色
        const user = await User.findById(userId);
        if (user) {
            if (!user.roles.includes('clubAdmin')) {
                user.roles.push('clubAdmin');
                await user.save();
            }
        }

        // 保存社团变更
        await club.save();

        res.status(200).json({ message: '管理员设置成功' });
    } catch (error) {
        console.error('设置社团管理员失败:', error);
        res.status(500).json({ message: '设置社团管理员失败', error: error.message });
    }
});

// 创建社团活动
app.post('/clubs/:clubId/activities', async (req, res) => {
    try {
        const { clubId } = req.params;
        const {
            activename,
            activetime,
            endTime,
            activeadd,
            description,
            maxParticipants,
            poster
        } = req.body;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 创建新活动
        const newActivity = new Activity({
            activename,
            activetime,
            endTime,
            activeadd,
            description,
            club: clubId,
            maxParticipants: maxParticipants || 50,
            poster,
            status: 'upcoming'
        });

        // 保存活动
        await newActivity.save();

        res.status(201).json({
            message: '活动创建成功',
            activity: newActivity
        });
    } catch (error) {
        console.error('创建活动失败:', error);
        res.status(500).json({ message: '创建活动失败', error: error.message });
    }
});

// 更新社团活动
app.put('/clubs/:clubId/activities/:activityId', async (req, res) => {
    try {
        const { clubId, activityId } = req.params;
        const {
            activename,
            activetime,
            endTime,
            activeadd,
            description,
            maxParticipants,
            poster,
            status
        } = req.body;

        // 验证社团ID和活动ID
        if (!mongoose.Types.ObjectId.isValid(clubId) || !mongoose.Types.ObjectId.isValid(activityId)) {
            return res.status(400).json({ message: '无效的ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找活动
        const activity = await Activity.findById(activityId);
        if (!activity) {
            return res.status(404).json({ message: '活动未找到' });
        }

        // 验证活动是否属于该社团
        if (activity.club.toString() !== clubId) {
            return res.status(403).json({ message: '该活动不属于此社团' });
        }

        // 更新活动字段
        if (activename) activity.activename = activename;
        if (activetime) activity.activetime = activetime;
        if (endTime) activity.endTime = endTime;
        if (activeadd) activity.activeadd = activeadd;
        if (description) activity.description = description;
        if (maxParticipants) activity.maxParticipants = maxParticipants;
        if (poster) activity.poster = poster;
        if (status && ['upcoming', 'ongoing', 'completed'].includes(status)) {
            activity.status = status;
        }

        // 保存更新
        await activity.save();

        res.status(200).json({
            message: '活动更新成功',
            activity
        });
    } catch (error) {
        console.error('更新活动失败:', error);
        res.status(500).json({ message: '更新活动失败', error: error.message });
    }
});

// 删除社团活动
app.delete('/clubs/:clubId/activities/:activityId', async (req, res) => {
    try {
        const { clubId, activityId } = req.params;

        // 验证社团ID和活动ID
        if (!mongoose.Types.ObjectId.isValid(clubId) || !mongoose.Types.ObjectId.isValid(activityId)) {
            return res.status(400).json({ message: '无效的ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找活动
        const activity = await Activity.findById(activityId);
        if (!activity) {
            return res.status(404).json({ message: '活动未找到' });
        }

        // 验证活动是否属于该社团
        if (activity.club.toString() !== clubId) {
            return res.status(403).json({ message: '该活动不属于此社团' });
        }

        // 删除活动
        await Activity.findByIdAndDelete(activityId);

        res.status(200).json({ message: '活动删除成功' });
    } catch (error) {
        console.error('删除活动失败:', error);
        res.status(500).json({ message: '删除活动失败', error: error.message });
    }
});

// 直接报名活动（无需审核）
app.post('/clubs/:clubId/activities/:activityId/participants', async (req, res) => {
    try {
        const { clubId, activityId } = req.params;
        const {
            userId, username, realName, studentId, contact, remark,
            avatar, status = 'approved'
        } = req.body;

        console.log('活动报名数据:', req.body);

        // 验证参数
        if (!mongoose.Types.ObjectId.isValid(clubId) || !mongoose.Types.ObjectId.isValid(activityId)) {
            return res.status(400).json({ message: '无效的ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找活动
        const activity = await Activity.findById(activityId);
        if (!activity) {
            return res.status(404).json({ message: '活动未找到' });
        }

        // 验证活动是否属于该社团
        if (activity.club.toString() !== clubId) {
            return res.status(403).json({ message: '该活动不属于此社团' });
        }

        // 检查是否已达到人数上限
        if (activity.maxParticipants) {
            const approvedParticipants = activity.participants.filter(p => p.status === 'approved').length;
            if (approvedParticipants >= activity.maxParticipants) {
                return res.status(400).json({ message: '活动报名人数已达上限' });
            }
        }

        // 检查用户是否已报名
        const isAlreadyRegistered = activity.participants.some(p => p.userId === userId);
        if (isAlreadyRegistered) {
            return res.status(400).json({ message: '您已经报名过此活动' });
        }

        // 添加用户到报名列表（直接设置为已通过）
        const newParticipant = {
            userId,
            user: userId, // 存储用户引用
            username,
            realName,
            studentId,
            contact,
            remark,
            avatar,
            registerTime: new Date(),
            status: status || 'approved' // 默认为已通过
        };

        activity.participants.push(newParticipant);
        await activity.save();

        console.log('报名成功:', newParticipant);

        res.status(201).json({
            message: '活动报名成功',
            participant: newParticipant,
            activity
        });
    } catch (error) {
        console.error('活动报名失败:', error);
        res.status(500).json({ message: '活动报名失败', error: error.message });
    }
});

// 删除活动报名
app.delete('/clubs/:clubId/activities/:activityId/participants/:userId', async (req, res) => {
    try {
        const { clubId, activityId } = req.params;
        const userIdParam = req.params.userId; // 从URL获取用户ID参数

        console.log(`删除报名 - clubId: ${clubId}, activityId: ${activityId}, userIdParam: ${userIdParam}`);

        // 验证参数
        if (!mongoose.Types.ObjectId.isValid(clubId) || !mongoose.Types.ObjectId.isValid(activityId)) {
            return res.status(400).json({ message: '无效的社团ID或活动ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找活动
        const activity = await Activity.findById(activityId);
        if (!activity) {
            return res.status(404).json({ message: '活动未找到' });
        }

        // 验证活动是否属于该社团
        if (activity.club.toString() !== clubId) {
            return res.status(403).json({ message: '该活动不属于此社团' });
        }

        // 查找要删除的参与者索引，确保进行字符串比较
        const participantIndex = activity.participants.findIndex(p => {
            // 正确的字段是 p.user，不是 p.userId
            const participantUserIdStr = p.user ? p.user.toString() : null;
            if (!participantUserIdStr) {
                console.warn(`参与者记录缺少 user 字段: ${JSON.stringify(p)}`);
                return false;
            }
            // 与从URL参数获取的userIdParam进行比较
            return participantUserIdStr === userIdParam;
        });

        // 检查是否找到了参与者
        if (participantIndex === -1) {
            console.log(`数据库中未找到 userId 为 ${userIdParam} 的报名记录`);
            return res.status(404).json({ message: '未找到该用户的报名记录' });
        }

        console.log(`找到要删除的参与者索引: ${participantIndex}`);

        // 使用splice移除找到的参与者
        activity.participants.splice(participantIndex, 1);

        // 保存更新后的活动
        await activity.save();

        console.log(`报名删除成功，userId: ${userIdParam}`);

        res.status(200).json({
            message: '报名删除成功',
            activity // 返回更新后的活动信息，包含移除参与者后的列表
        });
    } catch (error) {
        console.error('删除活动报名失败:', error);
        res.status(500).json({ message: '删除活动报名失败', error: error.message });
    }
});

// 删除帖子
app.delete('/posts/:postId', async (req, res) => {
    try {
        const { postId } = req.params;

        // 验证帖子ID
        if (!mongoose.Types.ObjectId.isValid(postId)) {
            return res.status(400).json({ message: '无效的帖子ID' });
        }

        // 查找并删除帖子
        const deletedPost = await Post.findByIdAndDelete(postId);

        if (!deletedPost) {
            return res.status(404).json({ message: '帖子未找到' });
        }

        // 如果帖子有图片，可以选择从存储中删除
        if (deletedPost.image) {
            try {
                const bucket = app.locals.bucket;
                await bucket.delete(new ObjectId(deletedPost.image));
                console.log(`已删除帖子图片: ${deletedPost.image}`);
            } catch (imageError) {
                console.error('删除帖子图片失败:', imageError);
                // 继续执行，不因图片删除失败而中断操作
            }
        }

        // 如果帖子发布到了学校，从学校的posts数组中移除
        if (deletedPost.publishToSchool) {
            await School.updateOne(
                { _id: deletedPost.publishToSchool },
                { $pull: { posts: deletedPost._id } }
            );
        }

        res.status(200).json({
            message: '帖子删除成功',
            deletedPost
        });
    } catch (error) {
        console.error('删除帖子失败:', error);
        res.status(500).json({ message: '删除帖子失败' });
    }
});

// 更新社团信息
app.put('/clubs/:id', upload.single('clubimg'), async (req, res) => {
    try {
        const clubId = req.params.id;
        const { clubname, description } = req.body;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找社团
        const club = await Club.findById(clubId);
        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 更新社团字段
        if (clubname !== undefined) club.clubname = clubname;
        if (description !== undefined) club.description = description;

        // 处理上传的新图片
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex');
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });
            uploadStream.write(req.file.buffer);
            uploadStream.end();
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    // 删除旧图片（如果存在）
                    if (club.clubimg) {
                        bucket.delete(new ObjectId(club.clubimg)).catch(err => console.error("删除旧社团图片失败:", err));
                    }
                    club.clubimg = uploadStream.id.toString(); // 更新图片ID
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 保存更改
        const updatedClub = await club.save();
        res.status(200).json(updatedClub);

    } catch (error) {
        console.error('更新社团信息失败:', error);
        res.status(500).json({ message: '更新社团信息失败', error: error.message });
    }
});

// 删除社团
app.delete('/clubs/:id', async (req, res) => {
    try {
        const clubId = req.params.id;

        // 验证社团ID
        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 查找并删除社团
        const deletedClub = await Club.findByIdAndDelete(clubId);

        if (!deletedClub) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 从学校的clubs数组中移除该社团ID
        if (deletedClub.school) {
            await School.updateOne(
                { _id: deletedClub.school },
                { $pull: { clubs: deletedClub._id } }
            );
        }

        // [可选] 删除社团相关资源，如帖子、活动、成员关系、头像等
        // 1. 删除社团图片
        if (deletedClub.clubimg) {
            const bucket = app.locals.bucket;
            bucket.delete(new ObjectId(deletedClub.clubimg)).catch(err => console.error("删除社团图片失败:", err));
        }
        // 2. 删除社团发布的帖子？ (根据业务逻辑决定)
        // await Post.deleteMany({ clubId: deletedClub._id });
        // 3. 删除社团举办的活动？
        // await Activity.deleteMany({ club: deletedClub._id });
        // 4. 从用户的clubs数组中移除该社团ID？
        // await User.updateMany({ clubs: deletedClub._id.toString() }, { $pull: { clubs: deletedClub._id.toString() } });

        res.status(200).json({ message: '社团删除成功' });

    } catch (error) {
        console.error('删除社团失败:', error);
        res.status(500).json({ message: '删除社团失败', error: error.message });
    }
});

// 获取学校成员列表（分页）
app.get('/schools/:schoolId/users', async (req, res) => {
    try {
        const schoolId = req.params.schoolId;
        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;

        // 验证学校ID
        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }

        // 查找学校并仅选择 users 和 admin 字段
        const school = await School.findById(schoolId).select('users admin');
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 获取学校的用户ID列表
        const userIds = school.users || [];
        const total = userIds.length;

        // 根据分页获取当前页的用户ID
        const paginatedUserIds = userIds.slice(skip, skip + limit);

        // 查询这些用户的详细信息 (根据前端需要选择字段)
        const users = await User.find({ _id: { $in: paginatedUserIds } })
            .select('username avatar phone registration_time'); // 选择前端需要的字段

        res.status(200).json({
            users: users, // 直接返回查询到的用户
            schoolAdmins: school.admin, // 将学校管理员列表也返回给前端
            pagination: {
                total,
                page,
                totalPages: Math.ceil(total / limit)
            }
        });
    } catch (error) {
        console.error('获取学校成员列表失败:', error);
        res.status(500).json({ message: '获取学校成员列表失败', error: error.message });
    }
});

// 权限检查中间件 (示例，需要根据实际情况完善)
const checkSchoolAdmin = async (req, res, next) => {
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: '未授权' });
    }
    try {
        const decoded = jwt.verify(token, 'your_jwt_secret');
        const currentUser = await User.findById(decoded.id).select('roles school');
        if (!currentUser) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 系统管理员有权操作
        if (currentUser.roles.includes('systemAdmin')) {
            req.user = currentUser;
            return next();
        }

        // 学校管理员只能操作自己学校
        const schoolId = req.params.schoolId;
        if (!schoolId || !mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效或缺少学校ID' });
        }

        const school = await School.findById(schoolId).select('admin');
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 检查当前用户是否是该学校的管理员
        const isAdminOfSchool = school.admin.some(adminId => adminId.equals(currentUser._id));

        if (isAdminOfSchool) {
            req.user = currentUser;
            next();
        } else {
            return res.status(403).json({ message: '权限不足' });
        }
    } catch (error) {
        console.error('权限检查失败:', error);
        if (error.name === 'JsonWebTokenError') {
            return res.status(401).json({ message: '无效的令牌' });
        }
        return res.status(500).json({ message: '服务器内部错误' });
    }
};

// 设置学校管理员
app.put('/schools/:schoolId/admins/:userId', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, userId } = req.params;

        // 验证ID
        if (!mongoose.Types.ObjectId.isValid(schoolId) || !mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的学校ID或用户ID' });
        }

        // 查找学校
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 检查用户是否是学校成员 (users 数组包含的是 ObjectId)
        const isMember = school.users.some(memberId => memberId.equals(userId));
        if (!isMember) {
            return res.status(400).json({ message: '该用户不是学校成员' });
        }

        // 检查是否已经是管理员
        const isAdmin = school.admin.some(adminId => adminId.equals(userId));
        if (isAdmin) {
            return res.status(400).json({ message: '该用户已经是管理员' });
        }

        // 添加到管理员列表
        school.admin.push(userId);
        await school.save();

        res.status(200).json({ message: '设置管理员成功', admins: school.admin });

    } catch (error) {
        console.error('设置学校管理员失败:', error);
        res.status(500).json({ message: '设置学校管理员失败', error: error.message });
    }
});

// 取消学校管理员
app.delete('/schools/:schoolId/admins/:userId', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, userId } = req.params;

        // 验证ID
        if (!mongoose.Types.ObjectId.isValid(schoolId) || !mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的学校ID或用户ID' });
        }

        // 查找学校
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 检查是否是管理员
        const isAdmin = school.admin.some(adminId => adminId.equals(userId));
        if (!isAdmin) {
            return res.status(400).json({ message: '该用户不是管理员' });
        }

        // 从管理员列表移除
        school.admin = school.admin.filter(adminId => !adminId.equals(userId));
        await school.save();

        res.status(200).json({ message: '取消管理员成功', admins: school.admin });

    } catch (error) {
        console.error('取消学校管理员失败:', error);
        res.status(500).json({ message: '取消学校管理员失败', error: error.message });
    }
});

// 从学校移除成员
app.delete('/schools/:schoolId/users/:userId', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, userId } = req.params;

        // 验证ID
        if (!mongoose.Types.ObjectId.isValid(schoolId) || !mongoose.Types.ObjectId.isValid(userId)) {
            return res.status(400).json({ message: '无效的学校ID或用户ID' });
        }

        // 查找学校
        const school = await School.findById(schoolId);
        if (!school) {
            return res.status(404).json({ message: '学校未找到' });
        }

        // 检查用户是否是学校成员
        const userIndex = school.users.findIndex(memberId => memberId.equals(userId));
        if (userIndex === -1) {
            return res.status(404).json({ message: '该用户不是学校成员' });
        }

        // 不能移除自己 (如果执行者是学校管理员而不是系统管理员)
        const executor = req.user; // 来自 checkSchoolAdmin 中间件
        if (!executor.roles.includes('systemAdmin') && executor._id.equals(userId)) {
            return res.status(403).json({ message: '不能移除自己' });
        }

        // --- 开始移除操作 ---
        const userIdToRemove = new mongoose.Types.ObjectId(userId);

        // 1. 从学校的 users 数组中移除
        school.users.splice(userIndex, 1);

        // 2. 如果是管理员，也从 admin 数组中移除
        school.admin = school.admin.filter(adminId => !adminId.equals(userIdToRemove));

        // 3. 保存学校信息的更改
        await school.save();

        // 4. 更新用户文档，将 school 字段设为 null
        await User.updateOne({ _id: userIdToRemove }, { $unset: { school: "" } });

        // 5. 将用户从该学校的所有社团成员列表中移除
        //    a. 获取该学校的所有社团 ID
        const schoolClubIds = school.clubs || []; // 直接用 school.clubs，前面已经获取了 school 对象
        //    b. 遍历这些社团，移除指定用户
        if (schoolClubIds.length > 0) {
            await Club.updateMany(
                { _id: { $in: schoolClubIds } }, // 查找学校内的所有社团
                { $pull: { members: { user: userIdToRemove } } } // 从 members 数组中移除该用户
            );
            // 同时，如果该用户是这些社团的管理员，也应该移除其管理员身份
            await Club.updateMany(
                { _id: { $in: schoolClubIds }, admin: userIdToRemove }, // 查找该用户是管理员的社团
                { $pull: { admin: userIdToRemove } } // 从 admin 数组中移除
            );
        }

        res.status(200).json({ message: '成员移除成功' });

    } catch (error) {
        console.error('移除学校成员失败:', error);
        res.status(500).json({ message: '移除学校成员失败', error: error.message });
    }
});

// --- 社团创建申请相关 API ---



// 提交社团创建申请
app.post('/schools/:schoolId/club-applications', authenticateToken, upload.single('clubLogo'), async (req, res) => {
    try {
        const applicantId = req.userId;
        const { schoolId } = req.params;
        const { clubname, clubType, description, reason } = req.body;

        // 验证 School ID
        if (!mongoose.Types.ObjectId.isValid(schoolId)) {
            return res.status(400).json({ message: '无效的学校ID' });
        }
        const schoolExists = await School.findById(schoolId);
        if (!schoolExists) {
            return res.status(404).json({ message: '学校未找到' });
        }

        let logoId = null;
        // 处理 Logo 文件上传
        if (req.file) {
            const bucket = app.locals.bucket;
            const uniqueFilename = crypto.randomBytes(16).toString('hex') + path.extname(req.file.originalname);
            const uploadStream = bucket.openUploadStream(uniqueFilename, {
                contentType: req.file.mimetype
            });
            uploadStream.write(req.file.buffer);
            uploadStream.end();
            await new Promise((resolve, reject) => {
                uploadStream.on('finish', () => {
                    logoId = uploadStream.id.toString();
                    resolve();
                });
                uploadStream.on('error', reject);
            });
        }

        // 创建新的申请文档
        const newApplication = new ClubApplication({
            applicantId,
            schoolId,
            clubname,
            clubType,
            description,
            reason,
            logo: logoId,
            status: 'pending'
        });

        await newApplication.save();
        res.status(201).json({ message: '社团创建申请提交成功', application: newApplication });

    } catch (error) {
        console.error('提交社团创建申请失败:', error);
        res.status(500).json({ message: '提交社团创建申请失败', error: error.message });
    }
});

// 获取学校的社团创建申请列表 (需要管理员权限)
app.get('/schools/:schoolId/club-applications', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId } = req.params;
        const { status } = req.query; // 可选的状态筛选

        // 构建查询条件
        const query = { schoolId };
        if (status && ['pending', 'approved', 'rejected'].includes(status)) {
            query.status = status;
        }

        // 查询并填充申请人信息
        const applications = await ClubApplication.find(query)
            .populate('applicantId', 'username') // 填充申请人用户名
            .sort({ applyTime: -1 });

        // 格式化返回数据 (可选，但推荐)
        const formattedApplications = applications.map(app => ({
            _id: app._id,
            clubname: app.clubname,
            clubType: app.clubType,
            description: app.description,
            reason: app.reason,
            logo: app.logo,
            status: app.status,
            applyTime: app.applyTime,
            rejectReason: app.rejectReason,
            applicantUsername: app.applicantId?.username || '未知用户', // 处理可能不存在的用户
            applicantId: app.applicantId?._id // 保留申请人ID
        }));

        res.status(200).json(formattedApplications);

    } catch (error) {
        console.error('获取社团创建申请列表失败:', error);
        res.status(500).json({ message: '获取社团创建申请列表失败', error: error.message });
    }
});

// 批准社团创建申请 (需要管理员权限)
app.put('/schools/:schoolId/club-applications/:applicationId/approve', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, applicationId } = req.params;

        // 查找申请
        const application = await ClubApplication.findById(applicationId);
        if (!application || application.schoolId.toString() !== schoolId) {
            return res.status(404).json({ message: '申请未找到或不属于该学校' });
        }
        if (application.status !== 'pending') {
            return res.status(400).json({ message: '该申请已被处理' });
        }

        // --- 开始批准并创建社团 --- //

        // 1. 创建新社团
        const newClub = new Club({
            clubname: application.clubname,
            clubType: application.clubType,
            description: application.description,
            clubimg: application.logo, // 使用申请时上传的 logo
            school: application.schoolId,
            admin: [application.applicantId], // 申请人成为管理员
            members: [{ // 申请人成为社长
                user: application.applicantId,
                role: '社长',
                joinTime: new Date()
            }]
        });
        const savedClub = await newClub.save();

        // 2. 更新学校的社团列表
        await School.updateOne(
            { _id: application.schoolId },
            { $push: { clubs: savedClub._id } }
        );

        // 3. 更新申请人的社团列表
        await User.updateOne(
            { _id: application.applicantId },
            { $push: { clubs: savedClub._id.toString() } } // 存储 ObjectId 的字符串形式
        );

        // 4. 更新申请状态
        application.status = 'approved';
        await application.save();

        res.status(200).json({ message: '社团创建申请已批准', club: savedClub });

    } catch (error) {
        console.error('批准社团创建申请失败:', error);
        res.status(500).json({ message: '批准社团创建申请失败', error: error.message });
    }
});

// 拒绝社团创建申请 (需要管理员权限)
app.put('/schools/:schoolId/club-applications/:applicationId/reject', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, applicationId } = req.params;
        const { reason } = req.body; // 从请求体获取拒绝理由

        if (!reason) {
            return res.status(400).json({ message: '必须提供拒绝理由' });
        }

        // 查找申请
        const application = await ClubApplication.findById(applicationId);
        if (!application || application.schoolId.toString() !== schoolId) {
            return res.status(404).json({ message: '申请未找到或不属于该学校' });
        }
        if (application.status !== 'pending') {
            return res.status(400).json({ message: '该申请已被处理' });
        }

        // 更新申请状态和拒绝理由
        application.status = 'rejected';
        application.rejectReason = reason;
        await application.save();

        res.status(200).json({ message: '社团创建申请已拒绝', application });

    } catch (error) {
        console.error('拒绝社团创建申请失败:', error);
        res.status(500).json({ message: '拒绝社团创建申请失败', error: error.message });
    }
});

// --- 社团解散申请相关 API (待实现) --- //
// app.post('/schools/:schoolId/club-dissolution-applications', ...);
// app.get('/schools/:schoolId/club-dissolution-applications', ...);
// app.put('/schools/:schoolId/club-dissolution-applications/:applicationId/approve', ...);
// app.put('/schools/:schoolId/club-dissolution-applications/:applicationId/reject', ...);


// ... (其他路由如成员管理、学校管理等) ...

app.listen(PORT, () => {
    console.log(`Server is running on http://localhost:${PORT}`);
});

// ... (在 checkSchoolAdmin 中间件之后)

// 中间件：验证用户是否为社团社长 (需要放在 authenticateToken 之后)
const checkClubPresident = async (req, res, next) => {
    try {
        const userId = req.userId; // 从 authenticateToken 获取
        const clubId = req.params.clubId;

        if (!mongoose.Types.ObjectId.isValid(clubId)) {
            return res.status(400).json({ message: '无效的社团ID' });
        }

        // 只查询了 members 字段，没有查询 school 字段
        // const club = await Club.findById(clubId).select('members');
        // --- 修改后：同时查询 members 和 school 字段 ---
        const club = await Club.findById(clubId).select('members school');

        if (!club) {
            return res.status(404).json({ message: '社团未找到' });
        }

        // 查找当前用户是否是该社团的社长
        const presidentMember = club.members.find(member =>
            member.user.equals(userId) && member.role === '社长'
        );

        if (!presidentMember) {
            return res.status(403).json({ message: '只有社长才能执行此操作' });
        }

        req.club = club; // 可以将社团信息附加到请求对象供后续使用
        next();

    } catch (error) {
        console.error('社长权限检查失败:', error);
        res.status(500).json({ message: '服务器内部错误' });
    }
};

// ... (设置学校管理员 API 之前)

// --- 社团解散申请 API ---

// POST /clubs/:clubId/dissolution-applications - 提交社团解散申请 (仅社长)
app.post('/clubs/:clubId/dissolution-applications', authenticateToken, checkClubPresident, async (req, res) => {
    try {
        const { reason } = req.body;
        const clubId = req.params.clubId;
        const applicantId = req.userId;
        const club = req.club; // 从 checkClubPresident 中间件获取
        const schoolId = club.school; // 假设 ClubSchema 中有 school 字段

        if (!reason) {
            return res.status(400).json({ message: '必须提供解散原因' });
        }

        // 检查是否已有待处理的解散申请
        const existingApplication = await ClubDissolutionApplication.findOne({
            clubId: clubId,
            status: 'pending'
        });

        if (existingApplication) {
            return res.status(400).json({ message: '该社团已存在待处理的解散申请' });
        }

        const newApplication = new ClubDissolutionApplication({
            applicantId,
            clubId,
            schoolId,
            reason,
            // status 默认为 'pending', applyTime 默认为 Date.now
        });

        await newApplication.save();
        res.status(201).json({ message: '社团解散申请已提交', application: newApplication });

    } catch (error) {
        console.error('提交社团解散申请失败:', error);
        res.status(500).json({ message: '服务器内部错误' });
    }
});

// --- 社团解散申请相关 API (补充实现) --- //

// GET /schools/:schoolId/club-dissolution-applications - 获取学校的社团解散申请列表 (需要学校管理员权限)
app.get('/schools/:schoolId/club-dissolution-applications', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId } = req.params;
        const { status } = req.query; // 可选的状态筛选

        // 构建查询条件
        const query = { schoolId };
        if (status && ['pending', 'approved', 'rejected'].includes(status)) {
            query.status = status;
        }

        // 查询并填充申请人信息和社团信息
        const applications = await ClubDissolutionApplication.find(query)
            .populate('applicantId', 'username') // 填充申请人用户名
            .populate('clubId', 'clubname') // 填充社团名称
            .sort({ applyTime: -1 });

        // 格式化返回数据
        const formattedApplications = applications.map(app => ({
            _id: app._id,
            clubId: app.clubId?._id,
            clubName: app.clubId?.clubname || '未知社团', // 处理可能不存在的社团
            reason: app.reason,
            status: app.status,
            applyTime: app.applyTime,
            rejectReason: app.rejectReason,
            applicantUsername: app.applicantId?.username || '未知用户', // 处理可能不存在的用户
            applicantId: app.applicantId?._id
        }));

        res.status(200).json(formattedApplications);

    } catch (error) {
        console.error('获取社团解散申请列表失败:', error);
        res.status(500).json({ message: '获取社团解散申请列表失败', error: error.message });
    }
});

// app.post('/schools/:schoolId/club-dissolution-applications', ...);
// ... (其他待实现的解散申请 API)

// ... (在获取解散申请列表 API 之后)

// PUT /schools/:schoolId/club-dissolution-applications/:applicationId/approve - 批准社团解散申请 (需要学校管理员权限)
app.put('/schools/:schoolId/club-dissolution-applications/:applicationId/approve', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, applicationId } = req.params;

        // 查找申请
        const application = await ClubDissolutionApplication.findById(applicationId);
        if (!application || application.schoolId.toString() !== schoolId) {
            return res.status(404).json({ message: '解散申请未找到或不属于该学校' });
        }
        if (application.status !== 'pending') {
            return res.status(400).json({ message: '该解散申请已被处理' });
        }

        const clubIdToDelete = application.clubId;

        // --- 开始批准并解散社团 --- //

        // 1. 删除社团文档
        const deletedClub = await Club.findByIdAndDelete(clubIdToDelete);
        if (!deletedClub) {
            console.warn(`尝试解散的社团 ${clubIdToDelete} 未找到，可能已被删除`);
            // 即使社团已不存在，也继续完成申请处理
        }

        // 2. 从学校的 clubs 数组中移除该社团ID
        await School.updateOne(
            { _id: schoolId },
            { $pull: { clubs: clubIdToDelete } }
        );

        // 3. 从所有成员的 clubs 数组中移除该社团ID
        // 注意：User.clubs 存储的是字符串ID
        if (deletedClub && deletedClub.members && deletedClub.members.length > 0) {
            const memberUserIds = deletedClub.members.map(m => m.user);
            await User.updateMany(
                { _id: { $in: memberUserIds } },
                { $pull: { clubs: clubIdToDelete.toString() } }
            );
        }

        // 4. 更新申请状态
        application.status = 'approved';
        await application.save();

        // [可选] 删除社团相关资源，如图片、帖子、活动等
        if (deletedClub && deletedClub.clubimg) {
            const bucket = app.locals.bucket;
            bucket.delete(new ObjectId(deletedClub.clubimg)).catch(err => console.error("删除已解散社团的Logo失败:", err));
        }
        // await Post.deleteMany({ clubId: clubIdToDelete });
        // await Activity.deleteMany({ club: clubIdToDelete });

        res.status(200).json({ message: '社团解散申请已批准，社团已成功解散' });

    } catch (error) {
        console.error('批准社团解散申请失败:', error);
        res.status(500).json({ message: '批准社团解散申请失败', error: error.message });
    }
});

// ... (其他解散申请 API)

// ... (在批准解散申请 API 之后)

// PUT /schools/:schoolId/club-dissolution-applications/:applicationId/reject - 拒绝社团解散申请 (需要学校管理员权限)
app.put('/schools/:schoolId/club-dissolution-applications/:applicationId/reject', checkSchoolAdmin, async (req, res) => {
    try {
        const { schoolId, applicationId } = req.params;
        const { reason } = req.body; // 从请求体获取拒绝理由

        if (!reason) {
            return res.status(400).json({ message: '必须提供拒绝理由' });
        }

        // 查找申请
        const application = await ClubDissolutionApplication.findById(applicationId);
        if (!application || application.schoolId.toString() !== schoolId) {
            return res.status(404).json({ message: '解散申请未找到或不属于该学校' });
        }
        if (application.status !== 'pending') {
            return res.status(400).json({ message: '该解散申请已被处理' });
        }

        // 更新申请状态和拒绝理由
        application.status = 'rejected';
        application.rejectReason = reason;
        await application.save();

        res.status(200).json({ message: '社团解散申请已拒绝', application });

    } catch (error) {
        console.error('拒绝社团解散申请失败:', error);
        res.status(500).json({ message: '拒绝社团解散申请失败', error: error.message });
    }
});


// ... (其他路由如成员管理、学校管理等) ...

// ... (在删除帖子 API 之后)

// PUT /posts/:postId/like - 点赞/取消点赞帖子
app.put('/posts/:postId/like', authenticateToken, async (req, res) => {
    try {
        const { postId } = req.params;
        const userId = req.userId; // 从 authenticateToken 中间件获取

        // 验证 postId
        if (!mongoose.Types.ObjectId.isValid(postId)) {
            return res.status(400).json({ message: '无效的帖子ID' });
        }

        // 查找帖子
        const post = await Post.findById(postId);
        if (!post) {
            return res.status(404).json({ message: '帖子未找到' });
        }

        // 检查用户是否已经点赞
        const likedIndex = post.likedBy.findIndex(id => id.equals(userId));

        let updatedLikes = 0;
        let isLiked = false;

        if (likedIndex > -1) {
            // 如果已点赞，则取消点赞 (从数组中移除)
            post.likedBy.splice(likedIndex, 1);
            isLiked = false;
        } else {
            // 如果未点赞，则添加点赞 (添加到数组)
            post.likedBy.push(userId);
            isLiked = true;
        }

        // 更新点赞数 (根据数组长度)
        updatedLikes = post.likedBy.length;

        // 保存帖子更改
        await post.save();

        res.status(200).json({
            message: isLiked ? '点赞成功' : '取消点赞成功',
            likes: updatedLikes,
            isLiked: isLiked // 返回当前的点赞状态
        });

    } catch (error) {
        console.error('处理点赞/取消点赞失败:', error);
        res.status(500).json({ message: '处理点赞/取消点赞失败', error: error.message });
    }
});

// ... (其他 API)

// ... (在点赞 API 之后)

// POST /posts/:postId/comments - 添加评论
app.post('/posts/:postId/comments', authenticateToken, async (req, res) => {
    try {
        const { postId } = req.params;
        const userId = req.userId;
        const { text } = req.body; // 从请求体获取评论内容

        // 验证 postId
        if (!mongoose.Types.ObjectId.isValid(postId)) {
            return res.status(400).json({ message: '无效的帖子ID' });
        }
        // 验证评论内容
        if (!text || text.trim() === '') {
            return res.status(400).json({ message: '评论内容不能为空' });
        }

        // 查找帖子
        const post = await Post.findById(postId);
        if (!post) {
            return res.status(404).json({ message: '帖子未找到' });
        }

        // 获取评论用户信息
        const user = await User.findById(userId).select('username avatar'); // 获取用户名和头像ID
        if (!user) {
            return res.status(404).json({ message: '用户未找到' });
        }

        // 创建新评论对象
        const newComment = {
            userId: userId,
            username: user.username,
            avatar: user.avatar, // 存储用户头像ID
            text: text,
            createdAt: new Date()
        };

        // 将新评论添加到帖子评论数组的末尾
        post.comments.push(newComment);

        // 保存帖子更改
        await post.save();

        // 返回新创建的评论 (包含生成的时间戳和可能的 _id)
        const addedComment = post.comments[post.comments.length - 1];
        res.status(201).json({
            message: '评论添加成功',
            comment: addedComment
        });

    } catch (error) {
        console.error('添加评论失败:', error);
        res.status(500).json({ message: '添加评论失败', error: error.message });
    }
});

// ... (其他 API)

// --- 新增：获取所有帖子（管理接口）---
app.get('/admin/posts', authenticateToken, async (req, res) => {
    try {
        // 权限检查：只有 systemAdmin 可以访问
        const requestingUser = await User.findById(req.userId).select('roles');
        if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
            return res.status(403).json({ message: '权限不足，只有系统管理员才能访问此接口' });
        }

        const page = parseInt(req.query.page) || 1;
        const limit = parseInt(req.query.limit) || 10;
        const skip = (page - 1) * limit;
        const { search } = req.query; // 获取搜索参数

        // 构建查询条件 (这里不需要 publishToHomepage 等限制)
        let query = {};
        if (search) {
            const searchRegex = new RegExp(search, 'i'); // 创建忽略大小写的正则表达式
            query.$or = [
                { title: { $regex: searchRegex } },
                { description: { $regex: searchRegex } }
            ];
        }

        // 计算总数 (应用搜索条件)
        const total = await Post.countDocuments(query);

        // 查询帖子列表，填充作者和社团信息 (应用搜索条件)
        const posts = await Post.find(query)
            .populate('authorId', 'username avatar') // 填充作者用户名和头像
            .populate('clubId', 'clubname') // 填充社团名称 (如果 clubId 存在)
            .populate('publishToSchool', 'name') // 填充发布学校名称
            .populate('publishToClubs', 'clubname') // 填充发布社团名称
            .sort({ createdAt: -1 })
            .skip(skip)
            .limit(limit)
            .lean(); // 使用 lean 提高性能

        // 格式化返回数据，添加计算字段和格式化范围
        const formattedPosts = posts.map(post => {
            // 计算点赞数和评论数
            const likesCount = post.likedBy?.length || 0;
            const commentsCount = post.comments?.length || 0;

            // 格式化发布范围
            let publishScope = [];
            if (post.publishToHomepage) {
                publishScope.push('首页');
            }
            if (post.publishToSchool) {
                publishScope.push(`学校: ${post.publishToSchool.name || '未知学校'}`);
            }
            if (post.publishToClubs && post.publishToClubs.length > 0) {
                const clubNames = post.publishToClubs.map(club => club.clubname || '未知社团').join(', ');
                publishScope.push(`社团: ${clubNames}`);
            }
            if (publishScope.length === 0) {
                publishScope.push('未指定范围');
            }

            return {
                ...post,
                author: post.authorId ? post.authorId.username : '未知作者',
                authorAvatar: post.authorId ? post.authorId.avatar : null,
                club: post.clubId ? post.clubId.clubname : '无所属社团',
                likesCount: post.likedBy?.length || 0,
                commentsCount: post.comments?.length || 0,
                publishScopeFormatted: publishScope.join(' | '),
                authorId: undefined,
                clubId: undefined,
                likedBy: undefined,
                // comments: undefined
            };
        });

        res.status(200).json({
            posts: formattedPosts,
            pagination: {
                total,
                page,
                limit,
                totalPages: Math.ceil(total / limit)
            }
        });

    } catch (error) {
        console.error('获取管理帖子列表失败:', error);
        res.status(500).json({ message: '获取管理帖子列表失败' });
    }
});

// ... (其他 API)

// --- 新增：更新帖子发布范围（管理接口）---
app.put('/admin/posts/:postId/scope', authenticateToken, async (req, res) => {
    try {
        // 权限检查：只有 systemAdmin 可以访问
        const requestingUser = await User.findById(req.userId).select('roles');
        if (!requestingUser || !requestingUser.roles.includes('systemAdmin')) {
            return res.status(403).json({ message: '权限不足，只有系统管理员才能修改发布范围' });
        }

        const { postId } = req.params;
        const { publishToHomepage, publishToSchool, publishToClubs } = req.body;

        // 验证 Post ID
        if (!mongoose.Types.ObjectId.isValid(postId)) {
            return res.status(400).json({ message: '无效的帖子ID' });
        }

        // 查找帖子
        const post = await Post.findById(postId);
        if (!post) {
            return res.status(404).json({ message: '帖子未找到' });
        }

        // --- 验证范围修改的合法性 ---

        // 1. 学校范围验证：只能是 null 或原始学校 ID
        const originalSchoolIdStr = post.publishToSchool ? post.publishToSchool.toString() : null;
        if (publishToSchool && publishToSchool !== originalSchoolIdStr) {
            return res.status(400).json({ message: '无法将帖子添加到新的学校，只能移除现有学校范围。' });
        }

        // 2. 社团范围验证：传入的社团 ID 必须是原始社团 ID 的子集
        const originalClubIdsStr = post.publishToClubs.map(id => id.toString());
        if (publishToClubs && Array.isArray(publishToClubs)) {
            const invalidClubs = publishToClubs.filter(clubId => !originalClubIdsStr.includes(clubId));
            if (invalidClubs.length > 0) {
                return res.status(400).json({ message: '无法将帖子添加到新的社团，只能移除现有社团范围。', invalidClubs });
            }
        } else if (publishToClubs != null) { // 处理非数组或 null 的情况
            return res.status(400).json({ message: '社团范围数据格式错误，应为 ID 数组。' });
        }

        // --- 更新帖子范围 --- //
        post.publishToHomepage = !!publishToHomepage; // 确保是布尔值
        post.publishToSchool = publishToSchool ? new mongoose.Types.ObjectId(publishToSchool) : null;
        post.publishToClubs = (publishToClubs || []).map(id => new mongoose.Types.ObjectId(id)); // 转换回 ObjectId 数组

        // 保存更改
        const updatedPost = await post.save();

        // [可选] 填充更新后的信息再返回，或者直接返回成功信息
        // 为了与 GET /admin/posts 保持一致，可以重新填充并格式化
        await updatedPost.populate(['authorId', 'clubId', 'publishToSchool', 'publishToClubs']);

        // 格式化返回数据
        const likesCount = updatedPost.likedBy?.length || 0;
        const commentsCount = updatedPost.comments?.length || 0;
        let publishScope = [];
        if (updatedPost.publishToHomepage) publishScope.push('首页');
        if (updatedPost.publishToSchool) publishScope.push(`学校: ${updatedPost.publishToSchool.name || '未知学校'}`);
        if (updatedPost.publishToClubs && updatedPost.publishToClubs.length > 0) {
            const clubNames = updatedPost.publishToClubs.map(club => club.clubname || '未知社团').join(', ');
            publishScope.push(`社团: ${clubNames}`);
        }
        if (publishScope.length === 0) publishScope.push('未指定范围');

        const formattedPost = {
            ...updatedPost.toObject(), // 使用 toObject() 获取普通对象
            author: updatedPost.authorId ? updatedPost.authorId.username : '未知作者',
            authorAvatar: updatedPost.authorId ? updatedPost.authorId.avatar : null,
            club: updatedPost.clubId ? updatedPost.clubId.clubname : '无所属社团',
            likesCount: likesCount,
            commentsCount: commentsCount,
            publishScopeFormatted: publishScope.join(' | '),
            createTimeFormatted: new Date(updatedPost.createdAt).toLocaleString(),
            // 清理不需要的原始字段
            authorId: undefined, clubId: undefined, publishToSchool: undefined,
            publishToClubs: undefined, likedBy: undefined, comments: undefined,
            __v: undefined // 移除版本号
        };


        res.status(200).json({ message: '帖子发布范围更新成功', post: formattedPost });

    } catch (error) {
        console.error('更新帖子发布范围失败:', error);
        res.status(500).json({ message: '更新帖子发布范围失败', error: error.message });
    }
});
